﻿using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace SpCop.Core
{
    //public class AssemblyResolver
    //{
    //    private static readonly string[] _extentions = new[] {".dll", ".exe"};
    //    private readonly ArrayList _directories = new ArrayList();

    //    public AssemblyResolver()
    //    {
    //        _directories.Add(".");
    //        _directories.Add("bin");
    //    }

    //    public void AddSearchDirectory(string directory)
    //    {
    //        _directories.Add(directory);
    //    }

    //    private static string GetAssemblyFile(AssemblyName reference, string gac)
    //    {
    //        var builder = new StringBuilder();
    //        builder.Append(reference.Version);
    //        builder.Append("__");
    //        byte[] publicKeyToken = reference.GetPublicKeyToken();
    //        for (int i = 0; i < publicKeyToken.Length; i++)
    //        {
    //            builder.Append(publicKeyToken[i].ToString("x2"));
    //        }
    //        return Path.Combine(Path.Combine(Path.Combine(gac, reference.Name), builder.ToString()),
    //                            reference.Name + ".dll");
    //    }

    //    private static Assembly GetAssemblyInGac(AssemblyName reference)
    //    {
    //        if ((reference.GetPublicKeyToken() != null) && (reference.GetPublicKeyToken().Length != 0))
    //        {
    //            string currentGacPath = GetCurrentGacPath();


    //            var strArray = new[] {"GAC_MSIL", "GAC_32", "GAC"};
    //            return (from t in strArray
    //                    select Path.Combine(Directory.GetParent(currentGacPath).FullName, t)
    //                    into gac let path = GetAssemblyFile(reference, gac)
    //                    where Directory.Exists(gac) && File.Exists(path) select Assembly.Load(path)).FirstOrDefault();
    //        }
    //        return null;
    //    }

    //    private static Assembly GetCorlib(AssemblyName reference)
    //    {
    //        if ((typeof (object).Assembly.GetName().Version == reference.Version) || IsZero(reference.Version))
    //        {
    //            return Assembly.GetAssembly(typeof (object));
    //        }
    //        string fullName =
    //            Directory.GetParent(Directory.GetParent(typeof (object).Module.FullyQualifiedName).FullName).FullName;

    //        switch (reference.Version.ToString())
    //        {
    //            case "1.0.3300.0":
    //                fullName = Path.Combine(fullName, "v1.0.3705");
    //                break;
    //            case "1.0.5000.0":
    //                fullName = Path.Combine(fullName, "v1.1.4322");
    //                break;
    //            default:
    //                if (reference.Version.ToString() != "2.0.0.0")
    //                {
    //                    throw new NotSupportedException("Version not supported: " + reference.Version);
    //                }
    //                fullName = Path.Combine(fullName, "v2.0.50727");
    //                break;
    //        }
    //        return File.Exists(Path.Combine(fullName, "mscorlib.dll"))
    //                   ? Assembly.Load(Path.Combine(fullName, "mscorlib.dll"))
    //                   : null;
    //    }

    //    private static string GetCurrentGacPath()
    //    {
    //        return
    //            Directory.GetParent(
    //                Directory.GetParent(Path.GetDirectoryName(typeof (Uri).Module.FullyQualifiedName)).FullName).
    //                FullName;
    //    }

    //    public string[] GetSearchDirectories()
    //    {
    //        return (string[]) _directories.ToArray();
    //    }

    //    private static bool IsZero(Version version)
    //    {
    //        return version != null &&
    //               ((((version.Major == 0) && (version.Minor == 0)) && (version.Build == 0)) && (version.Revision == 0));
    //    }


    //    public void RemoveSearchDirectory(string directory)
    //    {
    //        _directories.Remove(directory);
    //    }

    //    public virtual Assembly Resolve(AssemblyName name)
    //    {
    //        string directoryName = Path.GetDirectoryName(typeof (object).Module.FullyQualifiedName);
    //        Assembly assemblyInGac = SearchDirectory(name, _directories);
    //        if (assemblyInGac == null)
    //        {
    //            if (name.Version != null && IsZero(name.Version))
    //            {
    //                assemblyInGac = SearchDirectory(name, new[] {directoryName});
    //                if (assemblyInGac != null)
    //                {
    //                    return assemblyInGac;
    //                }
    //            }
    //            if (name.Name == "mscorlib")
    //            {
    //                assemblyInGac = GetCorlib(name);
    //                if (assemblyInGac != null)
    //                {
    //                    return assemblyInGac;
    //                }
    //            }
    //            assemblyInGac = GetAssemblyInGac(name);
    //            if (assemblyInGac != null)
    //            {
    //                return assemblyInGac;
    //            }
    //            assemblyInGac = SearchDirectory(name, new[] {directoryName});
    //            if (assemblyInGac == null)
    //            {
    //                return null;
    //                throw new FileNotFoundException("Could not resolve: " + name);
    //            }
    //        }
    //        return assemblyInGac;
    //    }

    //    public virtual Assembly Resolve(string fullName)
    //    {
    //        return Resolve(new AssemblyName(fullName));
    //    }

    //    private static Assembly SearchDirectory(AssemblyName name, IEnumerable directories)
    //    {
    //        try
    //        {
    //            return (
    //                       from string str in directories
    //                       from str2 in _extentions
    //                       select Path.Combine(str, name.Name + str2)
    //                       into path
    //                       where File.Exists(path)
    //                       select Assembly.LoadFile(Path.GetFullPath(path)))
    //                .FirstOrDefault();
    //        }
    //        catch
    //        {
    //            return null;
    //        }
    //    }
    //}
}